package com.nl.lib_core.tool

import android.annotation.SuppressLint
import android.text.TextUtils
import java.text.DateFormat
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.*
import kotlin.math.ceil
import kotlin.math.roundToInt

/** 作者: wangfei 创建时间: 2021/9/1 包名: com.nl.lib_core.util 类名: DateUtil */
object DateUtil {

  /**
   * 获取当前时间的位置：一天24小时以半小时为单位划分为48个单元格
   * @return
   */
  val currTimePosition: Int
    get() {
      val calendar = Calendar.getInstance()
      calendar.time = Date()
      return ceil(
              (calendar.get(Calendar.HOUR_OF_DAY) * 60 + calendar.get(Calendar.MINUTE)).toDouble() /
                  30)
          .toInt()
    }

  enum class FormatType {
    yyyy,
    yyyyMM,
    yyyyMMdd,
    yyyyMMddHHmm,
    yyyyMMddHHmmss,
    MMdd,
    HHmm,
    MM,
    dd,
    MMddHHmm
  }

  /** 格式化时间字符串 */
  @SuppressLint("SimpleDateFormat")
  fun formatDate(time: String, formatStr: String): String {
    val setdate = parseTime(time)
    val sdf = SimpleDateFormat(formatStr)
    return sdf.format(setdate)
  }

  fun formatDate(time: String, type: FormatType): String {
    if (TextUtils.isEmpty(time)) {
      return ""
    }
    val date = parseTime(time)
    return formatDate(date, type)
  }

  fun formatDate(time: String, fromtype: FormatType, totype: FormatType): String {
    if (TextUtils.isEmpty(time)) {
      return ""
    }
    val date = parseTime(time, fromtype)
    return formatDate(date, totype)
  }

  fun formatDate(time: Date?, type: FormatType): String {
    if (time == null) {
      return ""
    }
    val sdf = getSimpleDateFormat(type)
    return sdf.format(time)
  }

  @SuppressLint("SimpleDateFormat")
  private fun getSimpleDateFormat(type: FormatType): SimpleDateFormat {
    val sdf: SimpleDateFormat =
        when (type) {
          FormatType.yyyy -> SimpleDateFormat("yyyy")
          FormatType.yyyyMM -> SimpleDateFormat("yyyy-MM")
          FormatType.yyyyMMdd -> SimpleDateFormat("yyyy-MM-dd")
          FormatType.yyyyMMddHHmm -> SimpleDateFormat("yyyy-MM-dd HH:mm")
          FormatType.yyyyMMddHHmmss -> SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
          FormatType.MMdd -> SimpleDateFormat("MM-dd")
          FormatType.HHmm -> SimpleDateFormat("HH:mm")
          FormatType.MM -> SimpleDateFormat("MM")
          FormatType.dd -> SimpleDateFormat("dd")
          FormatType.MMddHHmm -> SimpleDateFormat("MM-dd HH:mm")
        }
    return sdf
  }

  /** 将时间字符串转化为date */
  @SuppressLint("SimpleDateFormat")
  fun parseTime(dateStr: String, formatStr: String): Date? {
    var date: Date? = null
    try {
      val sdf = SimpleDateFormat(formatStr)
      date = sdf.parse(dateStr)
    } catch (e: ParseException) {
      e.printStackTrace()
    }

    return date
  }

  /** 将字符串转换成date */
  @SuppressLint("SimpleDateFormat")
  fun parseTime(time: String): Date? {
    val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
    var date: Date? = null
    try {
      date = sdf.parse(time)
    } catch (e: Exception) {
      e.printStackTrace()
    }

    return date
  }

  /** 将字符串转换成date */
  fun parseTime(time: String, type: FormatType): Date? {
    var date: Date? = null
    val sdf = getSimpleDateFormat(type)
    try {
      date = sdf.parse(time)
    } catch (e: Exception) {
      e.printStackTrace()
    }

    return date
  }

  /** 增/减 offset 后的日期 */
  fun addAndSubtractDate(offset: Int, date: Date, unit: Int): Date {
    val calendar = Calendar.getInstance()
    calendar.time = date
    if (unit == Calendar.MONTH) {
      calendar.set(Calendar.DATE, 1)
    }
    calendar.set(unit, calendar.get(unit) + offset)
    return calendar.time
  }

  fun getDistanceTimeSecond(str1: String?, str2: String?, type: FormatType): Long {
    val df: DateFormat = getSimpleDateFormat(type)
    val one: Date
    val two: Date
    var day: Long = 0 // 天数
    var hour: Long = 0 // 小时
    var min: Long = 0 // 分钟
    var second: Long = 0 // 秒
    try {
      one = df.parse(str1)
      two = df.parse(str2)
      val time1 = one.time
      val time2 = two.time
      val diff: Long = time2 - time1
      day = diff / (24 * 60 * 60 * 1000)
      hour = diff / (60 * 60 * 1000) - day * 24
      min = diff / (60 * 1000) - day * 24 * 60 - hour * 60
      second = ((diff / (1000)) - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60)
    } catch (e: ParseException) {
      e.printStackTrace()
    }
    return day * 24 * 60 * 60 + hour * 60 * 60 + min * 60 + second
  }

  /** 计算两个日期之间相差的天数 */
  @Throws(ParseException::class)
  @SuppressLint("SimpleDateFormat")
  fun daysBetween(smdate: Date, bdate: Date): Int {
    var smdate = smdate
    var bdate = bdate
    val sdf = SimpleDateFormat("yyyy-MM-dd")
    smdate = sdf.parse(sdf.format(smdate))
    bdate = sdf.parse(sdf.format(bdate))
    val cal = Calendar.getInstance()
    cal.time = smdate
    val time1 = cal.timeInMillis
    cal.time = bdate
    val time2 = cal.timeInMillis
    val betweenDays = (time2 - time1) / (1000 * 3600 * 24)
    return Integer.parseInt(betweenDays.toString())
  }

  /** 比较日期大小 */
  @Throws(ParseException::class)
  @SuppressLint("SimpleDateFormat")
  fun compareDate(smdate: Date, bdate: Date): Int {
    var smdate = smdate
    var bdate = bdate
    val sdf = SimpleDateFormat("yyyy-MM-dd")
    smdate = sdf.parse(sdf.format(smdate))
    bdate = sdf.parse(sdf.format(bdate))
    val cal = Calendar.getInstance()
    cal.time = smdate
    val time1 = cal.timeInMillis
    cal.time = bdate
    val time2 = cal.timeInMillis
    return if (time1 == time2) {
      0
    } else if (time1 > time2) {
      -1
    } else {
      1
    }
  }

  /** 根据日期算周几 */
  fun whatDay(date: Date): String {
    val calendar = Calendar.getInstance() // 获得一个日历
    calendar.time = date
    val year = calendar.get(Calendar.YEAR)
    val month = calendar.get(Calendar.MONTH)
    val day = calendar.get(Calendar.DATE)
    calendar.set(year, month, day) // 设置当前时间,月份是从0月开始计算
    val number = calendar.get(Calendar.DAY_OF_WEEK) // 周表示1-7，是从周日开始，
    val str = arrayOf("", "周日", "周一", "周二", "周三", "周四", "周五", "周六")
    return str[number]
  }

  fun formatSecondToHourMinuteSecond(second: Int): String {
    var h = 0
    var d = 0
    var s = 0
    val temp = second % 3600
    if (second > 3600) {
      h = second / 3600
      if (temp != 0) {
        if (temp > 60) {
          d = temp / 60
          if (temp % 60 != 0) {
            s = temp % 60
          }
        } else {
          s = temp
        }
      }
    } else {
      d = second / 60
      if (second % 60 != 0) {
        s = second % 60
      }
    }
    return h.toString() + "时" + d + "分" + s + "秒"
  }

  fun formatSecondToHourMinute(duration: Int): String {
    if (duration < 60) {
      return duration.toString() + "秒"
    } else if (duration < 60 * 60) {
      return (duration.toFloat() / 60).roundToInt().toString() + "分钟"
    } else {
      val second = duration % (60 * 60)
      return if (second == 0) {
        (duration / (60 * 60)).toString() + "小时"
      } else {

        val round = (second.toFloat() / 60).roundToInt()
        if (round == 0) {
          (duration / (60 * 60)).toString() + "小时"
        } else {
          if (round == 60) {
            (duration / (60 * 60) + 1).toString() + "小时"
          } else {
            (duration / (60 * 60)).toString() + "小时" + round + "分钟"
          }
        }
      }
    }
  }

  /**
   * 说明 小于1分钟：”刚刚“ 小于1小时：”X分钟前“ 小于一天：”X小时前“ 小于一月：”X天前“ 小于一年：6-23 大于一年：2015-6-23
   *
   * @param dateStr
   * @return
   */
  @SuppressLint("SimpleDateFormat")
  fun formatTimeToDay(dateStr: String): String {
    val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
    val sdf2 = SimpleDateFormat("MM-dd")
    val sdf3 = SimpleDateFormat("yyyy-MM-dd")
    try {
      val date = sdf.parse(dateStr)

      val minute = ((System.currentTimeMillis() - date.time) / 1000 / 60).toInt()
      return if (minute <= 0) {
        "刚刚"
      } else if (minute / 60 == 0) {
        minute.toString() + "分钟前"
      } else if (minute / (60 * 24) == 0) {
        (minute / 60).toString() + "小时前"
      } else if (minute / (60 * 24 * 30) == 0) {
        (minute / (60 * 24)).toString() + "天前"
      } else if (minute / (60 * 24 * 30 * 12) == 0) {
        sdf2.format(date)
      } else {
        sdf3.format(date)
      }
    } catch (e: Exception) {
      e.printStackTrace()
    }

    return dateStr
  }

  /**
   * 获取几个小时以后的时间戳
   *
   * @param hour
   * @return
   */
  fun getLaterTimeByHour(hour: Int): String {
    val d = Date()
    val now = Calendar.getInstance()
    now.time = d
    now.set(Calendar.HOUR, now.get(Calendar.HOUR) + hour)
    // now.set(Calendar.MINUTE, now.get(Calendar.MINUTE) + 30);
    val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
    return sdf.format(now.time)
  }

  /**
   * 获取几天以后的时间戳
   *
   * @param day
   * @return
   */
  fun getLaterTimeByDay(day: Int): String {
    return getLaterTimeByHour(day * 24)
  }

  /**
   * 获取给定时间以后几天的时间戳
   * @param date
   * @param day
   * @return
   */
  fun getLaterTimeByDay(date: String, day: Int): String {
    val calendar = Calendar.getInstance()
    calendar.time = parseTime(date, FormatType.yyyyMMdd)
    calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) + day * 24)
    val sdf = SimpleDateFormat("yyyy-MM-dd")
    return sdf.format(calendar.time)
  }

  @Throws(java.lang.Exception::class)
  fun getAge(birthDay: Date): Int {
    val cal = Calendar.getInstance()
    require(!cal.before(birthDay)) { // 出生日期晚于当前时间，无法计算
      "The birthDay is before Now.It's unbelievable!"
    }
    val yearNow = cal[Calendar.YEAR] // 当前年份
    val monthNow = cal[Calendar.MONTH] // 当前月份
    val dayOfMonthNow = cal[Calendar.DAY_OF_MONTH] // 当前日期
    cal.time = birthDay
    val yearBirth = cal[Calendar.YEAR]
    val monthBirth = cal[Calendar.MONTH]
    val dayOfMonthBirth = cal[Calendar.DAY_OF_MONTH]
    var age = yearNow - yearBirth // 计算整岁数
    if (monthNow <= monthBirth) {
      if (monthNow == monthBirth) {
        if (dayOfMonthNow < dayOfMonthBirth) age-- // 当前日期在生日之前，年龄减一
      } else {
        age-- // 当前月份在生日之前，年龄减一
      }
    }
    return age
  }
}
